﻿// HSS.Forms.AppUserData.cs
// ----------------------------------------------------------------------------
// Licensed under the MIT license
// http://www.opensource.org/licenses/mit-license.html
// ----------------------------------------------------------------------------
// HighSpeed-Solutions, LLC
// Copyright (c) 2001-2010
// ----------------------------------------------------------------------------
// File:       AppUserData.cs
// Author:     HSS\gbanta
// Created:    08/12/2010
// Modified:   12/04/2010
// ----------------------------------------------------------------------------
namespace HSS.Forms
{
	#region Using Directives
	using System;
	using System.IO;
	using System.Text;
	using System.Xml;

	#endregion

	#region AppUserData
	/// <summary>
	/// AppUserData allows setting general Properties, Configurations and other User Specific Data
	/// in a convenient storage machanism that supports persisting to/from a File.
	/// </summary>
	public static class AppUserData
	{
		#region Events
		/// <summary>
		/// An event notifying that the AppData has changed
		/// </summary>
		public static event EventHandler<AppDataChangedEventArgs> AppUserDataChanged;
		static void AppData_Changed(object sender, AppDataChangedEventArgs e)
		{
			if (AppUserDataChanged != null)
				AppUserDataChanged(null, e);
		}
		#endregion

		#region Fields
		static AppData appData;
		static string appDataName;
		static string appDataFileName;
		static string appDataXmlRootName;
		#endregion

		#region Constructor
		/// <summary>
		/// CCTOR
		/// </summary>
		static AppUserData()
		{
			AppUserData._folder = System.Windows.Forms.Application.UserAppDataPath;

			appData = new AppData();
			appDataName = typeof(AppUserData).Name;
			appDataXmlRootName = appDataName;
			appDataFileName = appDataName + ".xml";
			appData.AppDataChanged += new EventHandler<AppDataChangedEventArgs>(AppData_Changed);

			AppUserData.Load();
		}
		#endregion

		#region Properties
		/// <summary>
		/// Has the AppUserData been initialized
		/// </summary>
		public static bool IsInitialized
		{
			get { return appData != null; }
		}
		/// <summary>
		/// Gets the folder where the appdata is to stored
		/// </summary>
		public static string Folder
		{
			get { return _folder; }
		} static string _folder;
		#endregion

		#region Methods
		/// <summary>
		/// Gets an Application Data Value
		/// </summary>
		/// <param name="key">The key to locate the value by</param>
		/// <returns>A string containing the value requested</returns>
		public static string GetString(string key)
		{
			return appData.Get<string>(key, string.Empty);
		}
		/// <summary>
		/// Gets an Application Data Value
		/// </summary>
		/// <typeparam name="T">The TypeOf value being retrieved</typeparam>
		/// <param name="key">The key to locate the value by</param>
		/// <param name="defaultValue">The default value to store</param>
		/// <returns>An object of the Type specified by T, containing the value</returns>
		public static T Get<T>(string key, T defaultValue)
		{
			return appData.Get(key, defaultValue);
		}
		/// <summary>
		/// Sets an Application Data Value
		/// </summary>
		/// <typeparam name="T">The TypeOf value being stored</typeparam>
		/// <param name="key">The key to reference the value by</param>
		/// <param name="value">The value to store</param>
		public static void Set<T>(string key, T value)
		{
			appData.Set(key, value);
		}
		/// <summary>
		/// Writes the Data to disk
		/// </summary>
		public static void Save()
		{
			if (!string.IsNullOrEmpty(_folder))
			{
				string fileName = Path.Combine(_folder, appDataFileName);
				using (XmlTextWriter writer = new XmlTextWriter(fileName, Encoding.UTF8))
				{
					writer.Formatting = Formatting.Indented;
					writer.WriteStartElement(appDataXmlRootName);
					appData.WriteAll(writer);
					writer.WriteEndElement();
				}
			}
		}

		internal static void Load()
		{
			if (appData == null)
				throw new InvalidOperationException("AppData is not initialized.");

			if (!Directory.Exists(_folder))
				Directory.CreateDirectory(_folder);

			LoadFromFile(Path.Combine(_folder, appDataFileName));
		}
		internal static bool LoadFromFile(string fileName)
		{
			if (!File.Exists(fileName))
				return false;

			try
			{
				using (XmlTextReader reader = new XmlTextReader(fileName))
				{
					while (reader.Read())
					{
						if (reader.IsStartElement())
						{
							if (reader.LocalName == appDataXmlRootName)
							{
								appData.ReadAll(reader, appDataXmlRootName);
								return true;
							}
						}
					}
				}
			}
			catch (XmlException ex)
			{
				MessageService.ShowError("Error loading AppData: " + ex.Message + "\n and has been restored to the default values.");
			}
			return false;
		}
		#endregion
	}
	#endregion
}